/* ----------------------------------
   IMPORT
   ---------------------------------- */
; always remember to import Java classes that are being used in this Jess file
(import dk.dtu.is.model.iec61850.ln.Zcev)
(import dk.dtu.is.utility.jess.StartIec61850ServerPolling)
(import dk.dtu.is.gui.UpdateGui)
(import dk.dtu.is.utility.jess.BeanSupport)

/* ----------------------------------
   GLOBAL
   ---------------------------------- */
; here you can add where you have located your files or other utilities
; remember to use the double backslash as folder separator!
;(defglobal ?*MYFILESPATH* = "C:\\Users\\UncleTom\\workspaces\\myworkspaces\\myproject\\bin")


(defglobal ?*max-cell-voltage* = 4.0)         		;V
(defglobal ?*high-red-cell-voltage* = 3.8)        	;V
(defglobal ?*high-yellow-cell-voltage* = 3.6)   	;V
(defglobal ?*low-yellow-cell-voltage* = 3.2)        ;V
(defglobal ?*low-red-cell-voltage* = 3.0)         	;V
(defglobal ?*min-cell-voltage* = 2.8)  				;V
(defglobal ?*max-diff-cells-voltage* = 0.08)    	;V
(defglobal ?*max-battery-voltage* = 410.0)      	;V     
(defglobal ?*red-temperature* = 40.0)           	;celsius
(defglobal ?*yellow-temperature* = 35.0)           	;celsius
(defglobal ?*max-temperature* = 85.0)           	;celsius (From battery manual)
(defglobal ?*max-current-charging* = 10.0)       	;A
(defglobal ?*max-current-discharging* = 10.0)    	;A  
(defglobal ?*max-soc* = 1.0)         				;%
(defglobal ?*high-red-soc* = 0.9)        			;%
(defglobal ?*high-yellow-soc* = 0.8)   				;%
(defglobal ?*low-yellow-soc* = 0.3)        			;%
(defglobal ?*low-red-soc* = 0.2)         			;%
(defglobal ?*min-soc* = 0.0)  						;%
 

/* ----------------------------------
   MODULES
   ---------------------------------- */
; you could use of using this module for your own functions or rules related to the Zcev object or the IEC 61850 server connection
;(defmodule Iec61850)

/* ----------------------------------
   TEMPLATE
   ---------------------------------- */
; map the bean Zcev into a class.
; this creates a template in Jess of the correspondent Java Object
; see 6.5 of "Jess In Action"
(defclass Zcev Zcev)
(defclass UpdateGui UpdateGui)
(bind ?updategui (new UpdateGui))

(call java.lang.Thread sleep 10000)

(deftemplate CELL (slot id(type INTEGER))(slot node(type INTEGER))(slot voltage (type FLOAT)))   ;first 2 numbers = node //last 2 numbers =cell
(deftemplate CELLSTRING extends CELL (slot temperature(type FLOAT)))
(deftemplate BATTERY extends CELLSTRING (slot current(type FLOAT)) (slot soc(type FLOAT)) (slot status) (slot ready))
(deftemplate SENSOR (slot value) (slot node(type INTEGER)))
(deftemplate CHARGER (slot status) (slot voltage(type FLOAT)) (slot current(type FLOAT)))
(deftemplate INVERTER (slot status) (slot voltage(type FLOAT)) (slot current(type FLOAT)))

/* ----------------------------------
   FUNCTION
   ---------------------------------- */

/*
   This is used to have a console after the program runs
 */
(deffunction command-loop ()
    "Explicitly start a command loop from within the system"
    ((new jess.Jesp ((engine) getInputRouter "t") (engine)) parse TRUE))

(deffunction FUNLIB::myprint (?message)
    (printout t ?message crlf)
    )


/* -------------------------------------------
  Initial facts 
---------------------------------------------*/
(assert(CHARGER (status idle)(voltage 0.0)(current 0.0)))
(assert(INVERTER (status idle)(voltage 0.0)(current 0.0)))
(assert(BATTERY (status idle)(current 0.0)(soc 0.0)(voltage 0.0)(temperature 0)(ready no)))

(assert(SENSOR (node 12)(value 0)))
(assert(SENSOR (node 23)(value 0)))
(assert(SENSOR (node 34)(value 0)))
(assert(SENSOR (node 45)(value 0)))
(assert(SENSOR (node 56)(value 0)))
(assert(SENSOR (node 67)(value 0)))
(assert(SENSOR (node 78)(value 0)))
(assert(SENSOR (node 89)(value 0)))
(assert(SENSOR (node 910)(value 0)))
(assert(SENSOR (node 1011)(value 0)))

(assert(CELLSTRING (node 1)(temperature 0)(voltage 0.0)))
(assert(CELLSTRING (node 2)(temperature 0)(voltage 0.0)))
(assert(CELLSTRING (node 3)(temperature 0)(voltage 0.0)))
(assert(CELLSTRING (node 4)(temperature 0)(voltage 0.0)))
(assert(CELLSTRING (node 5)(temperature 0)(voltage 0.0)))
(assert(CELLSTRING (node 6)(temperature 0)(voltage 0.0)))
(assert(CELLSTRING (node 7)(temperature 0)(voltage 0.0)))
(assert(CELLSTRING (node 8)(temperature 0)(voltage 0.0)))
(assert(CELLSTRING (node 9)(temperature 0)(voltage 0.0)))
(assert(CELLSTRING (node 10)(temperature 0)(voltage 0.0)))
(assert(CELLSTRING (node 11)(temperature 0)(voltage 0.0)))

(assert(CELL (node 1)(id 1)(voltage 0.0)))
(assert(CELL (node 1)(id 2)(voltage 0.0)))
(assert(CELL (node 1)(id 3)(voltage 0.0)))
(assert(CELL (node 1)(id 4)(voltage 0.0)))
(assert(CELL (node 1)(id 5)(voltage 0.0)))
(assert(CELL (node 1)(id 6)(voltage 0.0)))
(assert(CELL (node 1)(id 7)(voltage 0.0)))
(assert(CELL (node 1)(id 8)(voltage 0.0)))
(assert(CELL (node 1)(id 9)(voltage 0.0)))
(assert(CELL (node 1)(id 10)(voltage 0.0)))

(assert(CELL (node 2)(id 1)(voltage 0.0)))
(assert(CELL (node 2)(id 2)(voltage 0.0)))
(assert(CELL (node 2)(id 3)(voltage 0.0)))
(assert(CELL (node 2)(id 4)(voltage 0.0)))
(assert(CELL (node 2)(id 5)(voltage 0.0)))
(assert(CELL (node 2)(id 6)(voltage 0.0)))
(assert(CELL (node 2)(id 7)(voltage 0.0)))
(assert(CELL (node 2)(id 8)(voltage 0.0)))
(assert(CELL (node 2)(id 9)(voltage 0.0)))
(assert(CELL (node 2)(id 10)(voltage 0.0)))

(assert(CELL (node 3)(id 1)(voltage 0.0)))
(assert(CELL (node 3)(id 2)(voltage 0.0)))
(assert(CELL (node 3)(id 3)(voltage 0.0)))
(assert(CELL (node 3)(id 4)(voltage 0.0)))
(assert(CELL (node 3)(id 5)(voltage 0.0)))
(assert(CELL (node 3)(id 6)(voltage 0.0)))
(assert(CELL (node 3)(id 7)(voltage 0.0)))
(assert(CELL (node 3)(id 8)(voltage 0.0)))
(assert(CELL (node 3)(id 9)(voltage 0.0)))
(assert(CELL (node 3)(id 10)(voltage 0.0)))

(assert(CELL (node 4)(id 1)(voltage 0.0)))
(assert(CELL (node 4)(id 2)(voltage 0.0)))
(assert(CELL (node 4)(id 3)(voltage 0.0)))
(assert(CELL (node 4)(id 4)(voltage 0.0)))
(assert(CELL (node 4)(id 5)(voltage 0.0)))
(assert(CELL (node 4)(id 6)(voltage 0.0)))
(assert(CELL (node 4)(id 7)(voltage 0.0)))
(assert(CELL (node 4)(id 8)(voltage 0.0)))
(assert(CELL (node 4)(id 9)(voltage 0.0)))
(assert(CELL (node 4)(id 10)(voltage 0.0)))

(assert(CELL (node 5)(id 1)(voltage 0.0)))
(assert(CELL (node 5)(id 2)(voltage 0.0)))
(assert(CELL (node 5)(id 3)(voltage 0.0)))
(assert(CELL (node 5)(id 4)(voltage 0.0)))
(assert(CELL (node 5)(id 5)(voltage 0.0)))
(assert(CELL (node 5)(id 6)(voltage 0.0)))
(assert(CELL (node 5)(id 7)(voltage 0.0)))
(assert(CELL (node 5)(id 8)(voltage 0.0)))
(assert(CELL (node 5)(id 9)(voltage 0.0)))
(assert(CELL (node 5)(id 10)(voltage 0.0)))

(assert(CELL (node 6)(id 1)(voltage 0.0)))
(assert(CELL (node 6)(id 2)(voltage 0.0)))
(assert(CELL (node 6)(id 3)(voltage 0.0)))
(assert(CELL (node 6)(id 4)(voltage 0.0)))
(assert(CELL (node 6)(id 5)(voltage 0.0)))
(assert(CELL (node 6)(id 6)(voltage 0.0)))
(assert(CELL (node 6)(id 7)(voltage 0.0)))
(assert(CELL (node 6)(id 8)(voltage 0.0)))
(assert(CELL (node 6)(id 9)(voltage 0.0)))
(assert(CELL (node 6)(id 10)(voltage 0.0)))

(assert(CELL (node 7)(id 1)(voltage 0.0)))
(assert(CELL (node 7)(id 2)(voltage 0.0)))
(assert(CELL (node 7)(id 3)(voltage 0.0)))
(assert(CELL (node 7)(id 4)(voltage 0.0)))
(assert(CELL (node 7)(id 5)(voltage 0.0)))
(assert(CELL (node 7)(id 6)(voltage 0.0)))
(assert(CELL (node 7)(id 7)(voltage 0.0)))
(assert(CELL (node 7)(id 8)(voltage 0.0)))
(assert(CELL (node 7)(id 9)(voltage 0.0)))
(assert(CELL (node 7)(id 10)(voltage 0.0)))

(assert(CELL (node 8)(id 1)(voltage 0.0)))
(assert(CELL (node 8)(id 2)(voltage 0.0)))
(assert(CELL (node 8)(id 3)(voltage 0.0)))
(assert(CELL (node 8)(id 4)(voltage 0.0)))
(assert(CELL (node 8)(id 5)(voltage 0.0)))
(assert(CELL (node 8)(id 6)(voltage 0.0)))
(assert(CELL (node 8)(id 7)(voltage 0.0)))
(assert(CELL (node 8)(id 8)(voltage 0.0)))
(assert(CELL (node 8)(id 9)(voltage 0.0)))
(assert(CELL (node 8)(id 10)(voltage 0.0)))

(assert(CELL (node 9)(id 1)(voltage 0.0)))
(assert(CELL (node 9)(id 2)(voltage 0.0)))
(assert(CELL (node 9)(id 3)(voltage 0.0)))
(assert(CELL (node 9)(id 4)(voltage 0.0)))
(assert(CELL (node 9)(id 5)(voltage 0.0)))
(assert(CELL (node 9)(id 6)(voltage 0.0)))
(assert(CELL (node 9)(id 7)(voltage 0.0)))
(assert(CELL (node 9)(id 8)(voltage 0.0)))
(assert(CELL (node 9)(id 9)(voltage 0.0)))
(assert(CELL (node 9)(id 10)(voltage 0.0)))

(assert(CELL (node 10)(id 1)(voltage 0.0)))
(assert(CELL (node 10)(id 2)(voltage 0.0)))
(assert(CELL (node 10)(id 3)(voltage 0.0)))
(assert(CELL (node 10)(id 4)(voltage 0.0)))
(assert(CELL (node 10)(id 5)(voltage 0.0)))
(assert(CELL (node 10)(id 6)(voltage 0.0)))
(assert(CELL (node 10)(id 7)(voltage 0.0)))
(assert(CELL (node 10)(id 8)(voltage 0.0)))
(assert(CELL (node 10)(id 9)(voltage 0.0)))
(assert(CELL (node 10)(id 10)(voltage 0.0)))

(assert(CELL (node 11)(id 1)(voltage 0.0)))
(assert(CELL (node 11)(id 2)(voltage 0.0)))
(assert(CELL (node 11)(id 3)(voltage 0.0)))
(assert(CELL (node 11)(id 4)(voltage 0.0)))
(assert(CELL (node 11)(id 5)(voltage 0.0)))
(assert(CELL (node 11)(id 6)(voltage 0.0)))
(assert(CELL (node 11)(id 7)(voltage 0.0)))
(assert(CELL (node 11)(id 8)(voltage 0.0)))
(assert(CELL (node 11)(id 9)(voltage 0.0)))
(assert(CELL (node 11)(id 10)(voltage 0.0)))

/* -------------------------------------------
   RULES
   ----------------------------------------- */

(defrule current-update
   (Zcev (cur ?i))   
   ?k<-(BATTERY(voltage ?dummy)(ready ?r))
   =>
   (modify ?k(current ?i))
   ;(printout t "Current updated "?i " Ampere" crlf)
   (if (eq ?r no) then
        (assert(current-updated))
   )
   (?updategui refreshCurrent ?i)
)

(defrule battery-voltage-update
   (Zcev (vol ?v)) 
   ?k<-(BATTERY(soc ?dummy)(ready ?r))  
   =>
   (modify ?k(voltage ?v))
   ;(printout t "Battery voltage updated "?v " Volts" crlf)
   (if (eq ?r no) then
       (assert(battery-voltage-updated))
   )
   (?updategui refreshVoltage ?v)
)

(defrule soc-update
   (Zcev (soc ?soc1))   
   ?k<-(BATTERY(voltage ?dummy)(ready ?r))
   =>
   (modify ?k(soc ?soc1))
   ;(printout t "SOC updated "?soc1 " percent" crlf)
   (if (eq ?r no) then
       (assert(soc-updated))
   )
   (?updategui refreshSoc ?soc1)
)

(deffunction modcell (?n ?i ?x)
    (assert(modcellvolt ?n ?i ?x)) 
)

(deffunction stringvoltage (?n ?voltsum)
    (assert(stringvolt ?n ?voltsum))
)

(defrule cellVols-get 
   ;(declare (salience 30))
   (Zcev (cellVols $?cellVols))
   (BATTERY(ready ?r))
   =>
;    (?updategui emptyStatusList)
    (bind ?i 1)
    (bind ?n 1)
    (bind ?voltsum 0)
    (foreach ?x $?cellVols  
        (modcell ?n ?i ?x)                       ; Call to a function modcell
        (bind ?voltsum (+ ?voltsum ?x))
        ;(printout t "sumvolt "?voltsum crlf)
        (++ ?i)
        (if (> ?i 10)  
            then
            (stringvoltage ?n ?voltsum)
            (++ ?n)
            (bind ?i 1) 
            (bind ?voltsum 0)
            )
        )
    ;(printout t "Cellvolts updated "?voltsum crlf)
    (if (eq ?r no) then
        (assert(cell-voltage-updated))
    )
)

(defrule modcell
    (declare (salience 30))
    ?t<-(modcellvolt ?n ?i ?x)
    ?c<-(CELL (node ?n)(id ?i))
	=>
    (modify ?c(voltage (/ ?x 1000)))
    (retract ?t)
    )

(defrule string-voltage
    (declare (salience 20))
    ?c<-(stringvolt ?n ?voltsum)
    ?t<-(CELLSTRING (node ?n)(id ?i))
    (test (not (eq ?n nil)))             ;Needed to exclude battery to be true here
    (test (eq ?i nil))
    =>
    (modify ?t(voltage (/ ?voltsum 1000)))
    ;(printout t "Stringvolt updated "?voltsum " Ampere" crlf)
    (retract ?c)
)

(defrule system-ready
   ?x1<-(current-updated)
   ?x2<-(battery-voltage-updated)
   ?x3<-(soc-updated)
   ?x4<-(cell-voltage-updated)
  ;?x5<-(temp-updated)
   ?y<-(BATTERY(ready ?r))
   =>
   (modify ?y(ready yes))
   (printout t "System ready " crlf)
   (retract ?x1)
   (retract ?x2)
   (retract ?x3)
   (retract ?x4)
   ;(retract ?x5)
)

(defrule battery-status-discharge
    ?j<-(BATTERY(current ?i)(status ?s)(ready ?r))
    (test (not (= ?s discharging)))
    (test (< ?i 0))
    (test (eq ?r yes))
    =>
    (modify ?j(status discharging))
    (?updategui updateBatteryStatus "Discharging")
)

(defrule battery-status-charge
    ?j<-(BATTERY(current ?i)(status ?s)(ready ?r))
    (test (not (= ?s charging)))
    (test(> ?i 0))
    (test (eq ?r yes))
    =>
    (modify ?j(status charging))
    (?updategui updateBatteryStatus "Charging")
    )

(defrule battery-status-idle
    ?j<-(BATTERY(current ?i)(status ?s)(ready ?r))
    (test (not (= ?s idle)))
    (test(= ?i 0))
    (test (eq ?r yes))
    =>
    (modify ?j(status idle))
    (?updategui updateBatteryStatus "Idle")
    )

(defrule max-current-charging
   (BATTERY (current ?i)(ready ?r))
   (test(> ?i ?*max-current-charging*))    
   (test (eq ?r yes))        
   =>
   (?updategui updateCurrent "Maximum current while charging exceeded")   
)

(defrule max-current-discharging
   (BATTERY (current ?i)(ready ?r))
   (test(> ?i ?*max-current-discharging*))
   (test (eq ?r yes))     
   =>
   (?updategui updateCurrent "Maximum current while discharging exceeded")   
)

(defrule max-battery-voltage-exceeded
   (BATTERY (voltage ?volt)(ready ?r))
   (test(> ?volt ?*max-battery-voltage*))
   (test (eq ?r yes))
   =>
   (?updategui updateVoltage "Maximum battery voltage exceeded")   
)

(defrule max-cell-voltage-exceeded
    (BATTERY (ready ?r))
    (CELL(id ?i)(node ?n)(voltage ?volt))
    (test(> ?volt ?*max-cell-voltage*))
    (test (not (eq ?i nil)))
    (test (eq ?r yes))
    =>
    (?updategui updateCell "Maximum cell voltage exceeded" ?n ?i)   
    ;(assert(Event(property max-cell-voltage)(node ?n)(cell ?i)(value ?volt)(result exceeded)))
    )

(defrule high-red-cell-voltage-exceeded
    (BATTERY (ready ?r))
    (CELL(id ?i)(node ?n)(voltage ?volt))
    (test(> ?volt ?*high-red-cell-voltage*))
    (test (not (eq ?i nil)))
    (test (eq ?r yes))
    =>
    (?updategui updateCell "Critically high cell voltage" ?n ?i)  
    ;(assert(Event(property high-red-cell-voltage)(node ?n)(cell ?i)(value ?volt)(result red)))
    )

(defrule high-yellow-cell-voltage-exceeded
    (BATTERY (ready ?r))
    (CELL(id ?i)(node ?n)(voltage ?volt))
    (test(> ?volt ?*high-yellow-cell-voltage*))
    (test (not (eq ?i nil)))
    (test (eq ?r yes))
    =>
    (?updategui updateCell "High cell voltage" ?n ?i)  
    ;(assert(Event(property high-yellow-cell-voltage)(node ?n)(cell ?i)(value ?volt)(result yellow)))
    )

(defrule low-yellow-cell-voltage-exceeded
    (BATTERY (ready ?r))
    (CELL(id ?i)(node ?n)(voltage ?volt))
    (test(< ?volt ?*low-yellow-cell-voltage*))
    (test (not (eq ?i nil)))
    (test (eq ?r yes))
    =>
    (?updategui updateCell "Low cell voltage" ?n ?i)  
    ;(assert(Event(property low-yellow-cell-voltage)(node ?n)(cell ?i)(value ?volt)(result yellow)))
    )

(defrule low-red-cell-voltage-exceeded
    (BATTERY (ready ?r))
    (CELL(id ?i)(node ?n)(voltage ?volt))
    (test(< ?volt ?*low-red-cell-voltage*))
    (test (not (eq ?i nil)))
    (test (eq ?r yes))
    =>
    (?updategui updateCell "Critically low cell voltage" ?n ?i)      
    ;(assert(Event(property low-red-cell-voltage)(node ?n)(cell ?i)(value ?volt)(result red)))
    )

(defrule min-cell-voltage-exceeded
    (BATTERY (ready ?r))
    (CELL(id ?i)(node ?n)(voltage ?volt))
    (test(< ?volt ?*min-cell-voltage*))
    (test (not (eq ?i nil)))
    (test (eq ?r yes))
    =>
    (?updategui updateCell "Minimum cell voltage exceeded" ?n ?i)  
    ;(assert(Event(property min-cell-voltage)(node ?n)(cell ?i)(value ?volt)(result exceeded)))
    )

(defrule cell-voltage-difference-exceeded
    (BATTERY (ready ?r))
    (CELL(id ?id1)(node ?n)(voltage ?volt1))  ;having the same ?n enforces the same nodes
    (CELL(id ?id2)(node ?n)(voltage ?volt2))
    (test (not (eq ?id1 nil)))
    (test (not (eq ?id2 nil)))
    (test (= (- ?id1 ?id2) 1)) ; enforces cells to be next to each other
    (test (> (abs(- ?volt1 ?volt2)) ?*max-diff-cells-voltage*))  ;max difference in voltage reach
    (test (eq ?r yes))
    => 
    (?updategui updateCellDiff ?id1 ?id2 ?n ?n)  
    ;(assert(Event(property voltage-difference)(node ?n)(cell ?id1)(value (abs(- ?volt1 ?volt2)))(result exceeded)))
    ;(assert(Event(property voltage-difference)(node ?n)(cell ?id2)(value (abs(- ?volt1 ?volt2)))(result exceeded)))
)

(defrule cell-voltage-difference-exceeded2
    (BATTERY (ready ?r))
    (CELL(id 10)(node ?n1)(voltage ?volt1))  ;forcing id 1 and 10
    (CELL(id 1)(node ?n2)(voltage ?volt2))
    (test (= (- ?n2 ?n1) 1)) ;forcing n1 is followed by n2
    (test (> (abs(- ?volt1 ?volt2)) ?*max-diff-cells-voltage*))  ;max difference in voltage reach
    (test (eq ?r yes))
    =>
    (?updategui updateCellDiff 10 1 ?n1 ?n2)  
    ;(assert(Event(property voltage-difference)(node ?n1)(cell 10)(value (abs(- ?volt1 ?volt2)))(result exceeded)))
    ;(assert(Event(property voltage-difference)(node ?n2)(cell 1)(value (abs(- ?volt1 ?volt2)))(result exceeded)))
    )

(defrule max-soc-exceeded
    (BATTERY(soc ?soc)(ready ?r))
    (test(> ?soc ?*max-soc*))
    (test (eq ?r yes))
    =>
    (?updategui updateSoc "Error: State of Charge over 100%")  
    ;(assert(Event(property max-soc)(value ?soc)(result reading-error)))
    )

(defrule high-red-soc-exceeded
    (BATTERY(soc ?soc)(ready ?r))
    (test(> ?soc ?*high-red-soc*))
    (test (eq ?r yes))
    =>
    (?updategui updateSoc "Critically high State of Charge")  
    ;(assert(Event(property max-soc)(value ?soc)(result red)))
    )

(defrule high-yellow-soc-exceeded
    (BATTERY(soc ?soc)(ready ?r))
    (test(> ?soc ?*high-yellow-soc*))
    (test (eq ?r yes))
    =>
    (?updategui updateSoc "High State of Charge")  
    ;(assert(Event(property max-soc)(value ?soc)(result yellow)))
    )

(defrule low-yellow-soc-exceeded
    (BATTERY(soc ?soc)(ready ?r)(voltage ?v)(current ?i))
    (test(< ?soc ?*low-yellow-soc*))
    (test (eq ?r yes))
    =>
    (?updategui updateSoc "Low State of Charge")  
    ;(assert(Event(property max-soc)(value ?soc)(result yellow)))
    )

(defrule low-red-soc-exceeded
    (BATTERY(soc ?soc)(ready ?r))
    (test(< ?soc ?*low-red-soc*))
    (test (eq ?r yes))
    =>
    (?updategui updateSoc "Critically low State of Charge")  
    ;(assert(Event(property max-soc)(value ?soc)(result red)))
    )

(defrule min-soc-exceeded
    (BATTERY(soc ?soc)(ready ?r))
    (test(< ?soc ?*min-soc*))
    (test (eq ?r yes))
    =>
    ;(assert(Event(property max-soc)(value ?soc)(result reading-error)))
    (?updategui updateSoc "Error: State of Charge under 0%")  
)


;---------------------Temperature sensors---------------------------

;(defrule temp-update
;    (Zcev (temp ?temp1))
;    ?c<-(CELLSTRING(temperature ?t))
;    =>
;    (modify ?c(temperature ?temp1))
;    (if (eq ?r no) then
;        (assert(temp-updated))
;    )
;)

;(defrule string-temperature-exceeded
;    (BATTERY (ready ?r))
;    (CELLSTRING(id ?n1)(temperature ?temp))
;    (CELLSTRING(id ?n2)(temperature ?temp))
;    (test (not (eq ?id1 nil)))
;    (test (not (eq ?id2 nil)))
;    (test (eq ?n1 nil)))                        ;Needed to ensure the battery would not enter here  
;    (test (eq ?n2 nil)))
;    (test (= (abs(- ?n2 ?n1)) 1)) ;forcing n1 is followed by n2
;    (test (> ?temp ?*max-temperature*))
;    (test (eq ?r yes))
;    =>
;    (assert(Event(property temperature)(node ?n1)(value ?temp)(result exceeded)))
;    (assert(Event(property temperature)(node ?n2)(value ?temp)(result exceeded)))
;    )
;
;(defrule string-temperature-yellow
;    (BATTERY (ready ?r))
;    (CELLSTRING(id ?n1)(temperature ?temp))
;    (CELLSTRING(id ?n2)(temperature ?temp))
;    (test (not (eq ?id1 nil)))
;    (test (not (eq ?id2 nil)))
;    (test (eq ?n1 nil)))                        ;Needed to ensure the battery would not enter here  
;    (test (eq ?n2 nil)))
;    (test (= (abs(- ?n2 ?n1)) 1)) ;forcing n1 is followed by n2
;    (test (> ?temp ?*yellow-temperature*))
;    (test (eq ?r yes))
;    =>
;    (assert(Event(property temperature)(node ?n1)(value ?temp)(result yellow)))
;    (assert(Event(property temperature)(node ?n2)(value ?temp)(result yellow)))
;    )
;
;(defrule string-temperature-red
;    (BATTERY (ready ?r))
;    (CELLSTRING(id ?n1)(temperature ?temp))
;    (CELLSTRING(id ?n2)(temperature ?temp))
;    (test (not (eq ?id1 nil)))
;    (test (not (eq ?id2 nil)))
;    (test (eq ?n1 nil)))                        ;Needed to ensure the battery would not enter here  
;    (test (eq ?n2 nil)))
;    (test (= (abs(- ?n2 ?n1)) 1)) ;forcing n1 is followed by n2
;    (test (> (?temp ?*red-temperature*)))
;    (test (eq ?r yes))
;    =>
;    (assert(Event(property temperature)(node ?n1)(value ?temp)(result red)))
;    (assert(Event(property temperature)(node ?n2)(value ?temp)(result red)))
;    )

/* ----------------------------------
   ACTIONS
   ---------------------------------- */
; Actions: this part of the program contains commands to be executed by the jess interpreter.

;(watch all)

; load the userFunction into Jess
(load-function StartIec61850ServerPolling)
; call the user function
; it starts the connection with the server and pulls data that are pushed into the Zcev object
(start-iec61850-serverpolling)
;(watch facts)
;(reset)
;(run-until-halt)

;(command-loop)
